package com.relytosoft.mizar.media.display.services.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.relytosoft.dubhe.common.core.exception.ServiceException;
import com.relytosoft.dubhe.common.core.utils.TreeBuildUtils;
import com.relytosoft.dubhe.common.satoken.entity.CurrentUser;
import com.relytosoft.mizar.media.camera.api.feign.CameraFeignInService;
import com.relytosoft.mizar.media.display.api.entity.ViewDetail;
import com.relytosoft.mizar.media.display.api.entity.ViewForm;
import com.relytosoft.mizar.media.display.api.pojo.dto.ChannelRtspStreamDto;
import com.relytosoft.mizar.media.display.api.pojo.dto.ViewDetailDto;
import com.relytosoft.mizar.media.display.api.pojo.dto.ViewFormDto;
import com.relytosoft.mizar.media.display.api.pojo.vo.VideoPlayVo;
import com.relytosoft.mizar.media.display.services.mapper.ViewFormMapper;
import com.relytosoft.mizar.media.display.services.service.VideoService;
import com.relytosoft.mizar.media.display.services.service.ViewDetailService;
import com.relytosoft.mizar.media.display.services.service.ViewFormService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * 视图资源实现类
 *
 * @author hj
 * @version 1.0
 * @date 2022/4/22 16:26
 * @ClassName ViewFormServiceImpl
 */
@Service
public class ViewFormServiceImpl extends ServiceImpl<ViewFormMapper, ViewForm> implements ViewFormService {
    /**
     * 顶层父级ID
     */
    public static final int TOP_ID = 0;
    /**
     * 公共视图
     */
    public static final int PUBLIC_TYPE = 1;
    /**
     * 私有视图
     */
    public static final int PRIVATE_TYPE = 2;
    /**
     * 最多祖级个数
     */
    public static final int MAX_SIZE = 3;
    /**
     * 逗号常量
     */
    public static final String COMMA = ",";
    /**
     * 视图
     */
    public static final int VIEW = 2;
    /**
     * 视图组
     */
    public static final int VIEW_GROUP = 1;
    public static final String PUBLIC_GROUP_NAME = "公有视图";
    public static final int ENABLE = 1;

    @Resource
    private ViewDetailService viewDetailService;
   @Resource
   private VideoService videoService;
   @Resource
   private CameraFeignInService cameraFeignInService;




    /**
     * 获取视图资源树
     *
     * @return java.util.List<cn.hutool.core.lang.tree.Tree>
     * @author jgg
     * @date 2022/4/22 16:28
     * @param showGroup 是否只展示视图组
     */
    @Override
    public List<Tree<Integer>> selectTree(Boolean showGroup) {
        int currentUserId = CurrentUser.getCurrentUserId();
        LambdaQueryWrapper<ViewForm> wrapper = Wrappers.lambdaQuery();
        wrapper
                .eq(ViewForm::getStatus, ENABLE)
                .eq(showGroup,ViewForm::getViewType,VIEW_GROUP)
                .and(wq->{wq.or(wq1->wq1.eq(ViewForm::getParentId,TOP_ID));
                    wq.or(wq2->wq2.eq(ViewForm::getType,PUBLIC_TYPE));
                    wq.or(wq3->wq3.eq(ViewForm::getOwnerId,currentUserId).eq(ViewForm::getType,PRIVATE_TYPE));
                })
                .orderByAsc(ViewForm::getParentId)
                .orderByAsc(ViewForm::getViewType)
                .orderByAsc(ViewForm::getSort);
        List<ViewForm> list = list(wrapper);
        Map<Integer, List<ViewDetail>> groupMap = viewDetailService
                //获取视图明细信息
                .selectListByViewId(list.parallelStream().map(ViewForm::getId).collect(Collectors.toList()))
                .parallelStream()
                //分组存放
                .collect(Collectors.groupingBy(ViewDetail::getFormId));
        return TreeBuildUtils.build(list,(v, t) -> {
            Integer viewType = v.getViewType();
            Integer id = v.getId();
            List<ViewDetail> viewDetails = Optional.ofNullable(groupMap.get(id)).orElse(ListUtil.toList());
            t.setId(id);
            t.setParentId(v.getParentId());
            t.setName(v.getName());
            t.put("type",v.getType());
            t.put("sort",v.getSort());
            t.put("viewType",viewType);
            t.put("layout",v.getLayout());
            t.put("ownerId",v.getOwnerId());
            t.put("ancestor",v.getAncestor());
            if(viewType == VIEW) {
                t.put("viewDetails", viewDetails
                        .parallelStream()
                        .map(ViewDetailDto::buildDto)
                        .collect(Collectors.toList()));
            }
        });
    }

    /**
     * 新建视图资源
     *
     * @param form
     * @param viewDetails
     * @return boolean
     * @author jgg
     * @date 2022/4/22 17:40
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean insertViewForm(ViewForm form, List<ViewDetailDto> viewDetails) {

        //如果是私有类型视图这添加拥有者ID
        if (Objects.equals(form.getType(),PRIVATE_TYPE)){
            form.setOwnerId(CurrentUser.getCurrentUserId());
        }
        boolean save = save(form);
        if(form.getViewType() == VIEW_GROUP){
            return save;
        }
        Integer viewFormId = form.getId();
        List<ViewDetail> detailList = Optional.ofNullable(viewDetails)
                .orElseThrow(() -> new ServiceException("该视图没有绑定通道，添加失败！"))
                .parallelStream()
                .map(m -> m.buildViewDetail(viewFormId))
                .collect(Collectors.toList());
        return viewDetailService.saveBatch(detailList);
    }


    /**
     * 检查祖级个数是否符合标准
     * @param form
     */
    @Override
    public String checkAncestor(ViewFormDto form){
        Integer parentId = form.getParentId();
        if(parentId == 0){
            //
            throw new ServiceException("禁止对顶级视图资源进行操作！");
            /*if(form.getType() == PUBLIC_TYPE){
                throw new ServiceException("禁止创建公有视图组！");
            }else if(form.getViewType() != VIEW_GROUP){
                throw new ServiceException("请在视图组创建视图！");
            }
            return String.valueOf(TOP_ID);*/
        }
        String ancestor = getById(parentId).getAncestor();
        //获取祖级个数
        int size = StrUtil.split(ancestor, COMMA).size();
        if(size > MAX_SIZE && form.getViewType() == VIEW){
            throw new ServiceException("视图资源层级最多为三层！");
        }else if(size >= MAX_SIZE && form.getViewType() == VIEW_GROUP){
            throw new ServiceException("视图组层级最多为两层！");
        }
        return ancestor + COMMA +  parentId;
    }

    /**
     * 更新操作
     *
     * @param form
     * @param detailList
     * @return boolean
     * @author jgg
     * @date 2022/4/24 10:28
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateViewForm(ViewForm form, List<ViewDetail> detailList) {
        updateById(form);
        Integer formId = form.getId();
        viewDetailService.deleteByViewIds(ListUtil.toList(formId));
        boolean update = viewDetailService.saveBatch(detailList);
        return update;
    }

    /**
     * 删除视图资源
     * @param deleteIds
     * @return boolean
     * @author jgg
     * @date 2022/4/24 10:53
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteById(List<Integer> deleteIds) {
        viewDetailService.deleteByViewIds(deleteIds);
        return removeBatchByIds(deleteIds);
    }

    /**
     * 通过视图ID查询视频播放码流地址
     *
     * @param id
     * @return java.util.List<com.relytosoft.mizar.media.display.api.pojo.vo.VideoPlayVo>
     * @author jgg
     * @date 2022/4/24 11:21
     */
    @Override
    public List<VideoPlayVo> selectVideoPlay(Integer id) {
        //窗口布局大于4则显示子码流信息
        boolean isMain = getById(id).getLayout() <= 4;
        //查询码流及三方通道信息
        List<ChannelRtspStreamDto> dtoList = viewDetailService.selectRtspListByViewId(id);
        List<VideoPlayVo> videoPlayVos = videoService.buildPlayStreamUrl(dtoList.parallelStream()
                .map(m -> m.buildChannelPlayDetailQuery(isMain))
                .collect(Collectors.toList()));
        List<String> channelCodes = dtoList.parallelStream().map(ChannelRtspStreamDto::getPlatformChannelCode).collect(Collectors.toList());
        for (int i = 0 ; i < channelCodes.size(); i++){
            //设置三方通道id
            videoPlayVos.get(i).setPlatformChannelCode(channelCodes.get(i));
        }
        return videoPlayVos;
    }


    /**
     * 通过视图名称查询
     *
     * @param name
     * @return java.util.List<com.relytosoft.mizar.media.display.api.entity.ViewForm>
     * @author jgg
     * @date 2022/4/24 11:46
     */
    @Override
    public List<ViewFormDto> selectListByName(String name) {
        int currentUserId = CurrentUser.getCurrentUserId();
        LambdaQueryWrapper<ViewForm> wrapper = Wrappers.lambdaQuery();
        //添加查询条件
        wrapper.like(StrUtil.isNotBlank(name),ViewForm::getName,name)
                .eq(ViewForm::getViewType,VIEW)
                .and(w -> w.eq(ViewForm::getOwnerId,currentUserId).or().eq(ViewForm::getType,PUBLIC_TYPE))
                .orderByDesc(ViewForm::getType)
                .orderByAsc(ViewForm::getSort);
        List<ViewFormDto> collect = list(wrapper).parallelStream().map(ViewFormDto::buildDto).collect(Collectors.toList());
        return collect ;
    }
    /**
     * 检测视图组的名称
     * @author jgg
     * @param form
     *
     */
    @Override
    public void checkName(ViewFormDto form){
       LambdaQueryWrapper<ViewForm> wrapper = Wrappers.lambdaQuery();
        String name = form.getName();
        if(StrUtil.isBlank(name)){
            throw new ServiceException("请填写视图或视图组名称!");
        }
        wrapper.eq(ViewForm::getName,name)
                .eq(ViewForm::getType,form.getType())
                .eq(ViewForm::getViewType,form.getViewType())
                .ne(Objects.nonNull(form.getId()),ViewForm::getId,form.getId());
        if (Objects.equals(form.getType(),PRIVATE_TYPE)){
            wrapper.eq(ViewForm::getOwnerId,CurrentUser.getCurrentUserId());
        }
        if(count(wrapper) > 0){
            throw new ServiceException("视图名称已存在！");
        }
    }

    /**
     * @param dto
     */
    @Override
    public String check(ViewFormDto dto) {
        checkName(dto);
        return checkAncestor(dto);
    }

    /**
     * 查询删除ids
     *
     * @param id
     * @return List<Integer>
     * @author jgg
     */
    @Override
    public List<Integer> selectDeleteIds(Integer id) {
        ViewForm form = getById(id);
        Integer type = form.getType();
        Integer viewType = form.getViewType();
        Integer parentId = form.getParentId();
        if(parentId == TOP_ID){
            throw new ServiceException("禁止对顶级视图资源进行操作！");
        }
        List<ViewForm> deleteList = CollectionUtil.newArrayList();
        deleteList.add(form);
        if(viewType == VIEW_GROUP){
            LambdaQueryWrapper<ViewForm> wrapper = Wrappers.lambdaQuery();
            wrapper.like(ViewForm::getAncestor,form.getAncestor()+ COMMA + parentId + COMMA)
                    .or()
                    .eq(ViewForm::getParentId,form.getId());
            deleteList.addAll(list(wrapper));
        }
        return  deleteList.parallelStream().map(ViewForm::getId).collect(Collectors.toList());

    }
}
